#ifndef __EFX_H__
#define __EFX_H__

#include "common.h"
#include <stdbool.h>

typedef struct {
  sint32 X1;
  sint32 Y1;
} Efx_StatePT1_Type;

typedef struct {
  sint32 X1;
  sint32 X2;
  sint32 Y1;
} Efx_StateDT1Typ1_Type;

typedef struct {
  sint32 X1;
  sint32 Y1;
} Efx_StateDT1Typ2_Type;

typedef struct {
  sint32 X1;
  sint32 Y1;
} Efx_StatePD_Type;

typedef struct {
  sint32 K_C;
  sint32 Tv_C;
} Efx_ParamPD_Type;

typedef struct {
  sint32 X1;
  sint32 Y1;
} Efx_StateI_Type;

typedef struct {
  sint32 X1;
  sint32 Y1;
} Efx_StatePI_Type;

typedef struct {
  sint32 K_C;
  sint32 Tnrec_C;
} Efx_ParamPI_Type;

typedef struct {
  sint32 X1;
  sint32 X2;
  sint32 Y1;
} Efx_StatePID_Type;

typedef struct {
  sint32 K_C;
  sint32 Tv_C;
  sint32 Tnrec_C;
} Efx_ParamPID_Type;

typedef struct {
  sint32 Min_C;
  sint32 Max_C;
} Efx_Limits_Type;

typedef struct {
  sint32 sum;
  sint16 n;
  sint16 *p_beg;
  sint16 *p_end;
  sint16 *p_act;
} Efx_MovingAvrgS16_Type;

typedef struct {
  sint64 sum;
  sint32 n;
  sint32 *p_beg;
  sint32 *p_end;
  sint32 *p_act;
} Efx_MovingAvrgS32_Type;

typedef struct {
  uint32 SlopePos_u32;
  uint32 SlopeNeg_u32;
} Efx_ParamRamp_Type;

typedef struct {
  sint32 State_s32;
  sint8 Dir_s8;
  sint8 Switch_s8;
} Efx_StateRamp_Type;

typedef struct {
  sint32 dsintStatic;
  sint16 *lszStatic;
  sint16 *dtbufBegStatic;
  sint16 *dtbufEndStatic;
} Efx_DeadTimeParam_Type;

typedef struct {
  sint16 TimeHighLow;
  sint16 TimeLowHigh;
} Efx_DebounceParam_Type;

typedef struct {
  boolean XOld;
  sint32 Timer;
} Efx_DebounceState_Type;

// First computation
sint16 Efx_LpFilterFac1_s16s16s16_s16(sint16 Yn_1, sint16 Xn, sint16 fac);
sint16 Efx_LpFilterFac1_s16s16u16_s16(sint16 Yn_1, sint16 Xn, uint16 fac);
sint32 Efx_LpFilterFac1_s32s32u16_s32(sint32 Yn_1, sint32 Xn, uint16 fac);
uint16 Efx_LpFilterFac1_u16u16s16_u16(uint16 Yn_1, uint16 Xn, sint16 fac);
uint16 Efx_LpFilterFac1_u16u16u16_u16(uint16 Yn_1, uint16 Xn, uint16 fac);
uint8 Efx_LpFilterFac1_u8u8u8_u8(uint8 Yn_1, uint8 Xn, uint8 fac);
uint32 Efx_LpFilterFac1_u32u32u32_u32(uint32 Yn_1, uint32 Xn, uint32 fac);
uint32 Efx_LpFilterFac1_u32u32u16_u32(uint32 Yn_1, uint32 Xn, uint16 fac);

// Second computation
sint32 Efx_LpFilterFac1_s32s16u16_s32(sint32 Yn_1, sint16 Xn, uint16 fac);
uint32 Efx_LpFilterFac1_u32u16u16_u32(uint32 Yn_1, uint16 Xn, uint16 fac);

// Third computation
uint32 Efx_LpFilter_u32_u32(uint32 input, uint32 old_output, uint32 tau_const,
                            uint16 recurrence, uint8 reset, uint32 init_val,
                            uint8 *started);
sint32 Efx_LpFilter_s32_s32(sint32 input, sint32 old_output, uint32 tau_const,
                            uint16 recurrence, uint8 reset, sint32 init_val,
                            uint8 *started);

// First-order High-pass filter
sint16 Efx_HpFilter_u8_s16(sint16 Yn_1, uint8 Xn, uint8 Xn_1, uint16 K);
sint16 Efx_HpFilter_s8_s16(sint16 Yn_1, sint8 Xn, sint8 Xn_1, uint16 K);
sint32 Efx_HpFilter_u16_s32(sint32 Yn_1, uint16 Xn, uint16 Xn_1, uint16 K);
sint32 Efx_HpFilter_s16_s32(sint32 Yn_1, sint16 Xn, sint16 Xn_1, uint16 K);

// Exponential
sint32 Efx_Exp_s32_s32(sint32 Value1);

// Proportional Controller
void Efx_PCalc_s32(sint32 X_s32, sint32 *P_ps32, sint32 K_s32);
void Efx_PCalc(sint32 X_s32, sint32 *P_ps32, sint32 K_s32);
__STATIC_FORCEINLINE void Efx_PSetState(sint32 *P_s32, sint16 Y_s16) {
  *P_s32 = Y_s16 << 16;
}

__STATIC_FORCEINLINE sint16 Efx_POut_s16(const sint32 *P_ps32) {
  sint32 value = (*P_ps32) >> 16;
  if (value > S16_MAX) {
    value = S16_MAX;
  } else if (value < S16_MIN) {
    value = S16_MIN;
  }
  return (sint16)value;
}

__STATIC_FORCEINLINE sint8 Efx_POut_s8(const sint32 *P_ps32) {
  sint32 value = (*P_ps32) >> 16;
  if (value > S8_MAX) {
    value = S8_MAX;
  } else if (value < S8_MIN) {
    value = S8_MIN;
  }
  return (sint8)value;
}

// Proportional controller with first order time constant
void Efx_PT1Calc(sint32 X_s32, Efx_StatePT1_Type *State_cpst, sint32 K_s32,
                 sint32 TeQ_s32);
// void Efx_PT1Typ1Calc(sint32 X_s32, Efx_StatePT1_Type* State_cpst, sint32
// K_s32,
//                      sint32 TeQ_s32);
__STATIC_FORCEINLINE void Efx_PT1SetState(Efx_StatePT1_Type *State_cpst,
                                          sint32 X1_s32, sint16 Y1_s16) {
  State_cpst->Y1 = Y1_s16 << 16;
  State_cpst->X1 = X1_s32;
}
__STATIC_FORCEINLINE sint32 Efx_CalcTeQ_s32(sint32 T1rec_s32,
                                            sint32 dT_s32) { // ?
  return Efx_Exp_s32_s32(((sint32)(((sint64)T1rec_s32 * dT_s32) >> 31)));
}
__STATIC_FORCEINLINE sint32 Efx_CalcTeQApp_s32(sint32 T1rec_s32,
                                               sint32 dT_s32) { // ?
  assert((sint32)(((sint64)T1rec_s32 * dT_s32) >> 31) < S32_MAX);
  return (S32_MAX - (sint32)(((sint64)T1rec_s32 * dT_s32) >> 31)) /
         OneLtShift16;
}
__STATIC_FORCEINLINE sint16
Efx_PT1Out_s16(const Efx_StatePT1_Type *State_cpst) {
  sint16 output_value = (sint16)((sint32)(State_cpst->Y1) >> 16);
  if (output_value > S16_MAX) {
    output_value = S16_MAX;
  } else if (output_value < S16_MIN) {
    output_value = S16_MIN;
  }
  return output_value;
}
__STATIC_FORCEINLINE sint8 Efx_PT1Out_s8(const Efx_StatePT1_Type *State_cpst) {
  sint16 output_value = (uint16)((sint32)(State_cpst->Y1) >> 16);
  if (output_value > S8_MAX) {
    output_value = S8_MAX;
  } else if (output_value < S8_MIN) {
    output_value = S8_MIN;
  }
  return (sint8)output_value;
}

// Differential component with time delay : DT1
void Efx_DT1Typ1Calc(sint32 X_s32, Efx_StateDT1Typ1_Type *State_cpst,
                     sint32 K_s32, sint32 TeQ_s32, sint32 dT_s32);
void Efx_DT1Typ2Calc(sint32 X_s32, Efx_StateDT1Typ2_Type *State_cpst,
                     sint32 K_s32, sint32 TeQ_s32, sint32 dT_s32);
__STATIC_FORCEINLINE void Efx_DT1Typ1SetState(Efx_StateDT1Typ1_Type *State_cpst,
                                              sint32 X1_s32, sint32 X2_s32,
                                              sint16 Y1_s16) {
  State_cpst->Y1 = Y1_s16 << 16;
  State_cpst->X1 = X1_s32;
  State_cpst->X2 = X2_s32;
}
__STATIC_FORCEINLINE void Efx_DT1Typ2SetState(Efx_StateDT1Typ2_Type *State_cpst,
                                              sint32 X1_s32, sint16 Y1_s16) {
  State_cpst->Y1 = Y1_s16 << 16;
  State_cpst->X1 = X1_s32;
}
__STATIC_FORCEINLINE sint16
Efx_DT1Typ1Out_s16(const Efx_StateDT1Typ1_Type *State_cpst) {
  sint32 output_value = State_cpst->Y1 >> 16;
  if (output_value > S16_MAX) {
    output_value = S16_MAX;
  } else if (output_value < S16_MIN) {
    output_value = S16_MIN;
  }
  return (sint16)output_value;
}
__STATIC_FORCEINLINE sint8
Efx_DT1Typ1Out_s8(const Efx_StateDT1Typ1_Type *State_cpst) {
  sint32 output_value = State_cpst->Y1 >> 16;
  if (output_value > S8_MAX) {
    output_value = S8_MAX;
  } else if (output_value < S8_MIN) {
    output_value = S8_MIN;
  }
  return (sint8)output_value;
}
__STATIC_FORCEINLINE sint16
Efx_DT1Typ2Out_s16(const Efx_StateDT1Typ2_Type *State_cpst) {
  sint32 output_value = State_cpst->Y1 >> 16;
  if (output_value > S16_MAX) {
    output_value = S16_MAX;
  } else if (output_value < S16_MIN) {
    output_value = S16_MIN;
  }
  return (sint16)output_value;
}
__STATIC_FORCEINLINE sint8
Efx_DT1Typ2Out_s8(const Efx_StateDT1Typ2_Type *State_cpst) {
  sint32 output_value = State_cpst->Y1 >> 16;
  if (output_value > S8_MAX) {
    output_value = S8_MAX;
  } else if (output_value < S8_MIN) {
    output_value = S8_MIN;
  }
  return (sint8)output_value;
}

// Proportional and Differential controller
void Efx_PDCalc(sint32 X_s32, Efx_StatePD_Type *State_cpst,
                const Efx_ParamPD_Type *Param_cpst, sint32 dT_s32);
__STATIC_FORCEINLINE void Efx_PDSetState(Efx_StatePD_Type *State_cpst,
                                         sint32 X1_s32, sint16 Y1_s16) {
  State_cpst->Y1 = Y1_s16 << 16;
  State_cpst->X1 = X1_s32;
}
__STATIC_FORCEINLINE void Efx_PDSetParam(Efx_ParamPD_Type *Param_cpst,
                                         sint32 K_s32, sint32 Tv_s32) {
  Param_cpst->K_C = K_s32;
  Param_cpst->Tv_C = Tv_s32;
}
__STATIC_FORCEINLINE sint16 Efx_PDOut_s16(const Efx_StatePD_Type *State_cpcst) {
  sint32 output_value = State_cpcst->Y1 >> 16;
  if (output_value > S16_MAX) {
    output_value = S16_MAX;
  } else if (output_value < S16_MIN) {
    output_value = S16_MIN;
  }
  return (sint16)output_value;
}
__STATIC_FORCEINLINE sint8 Efx_PDOut_s8(const Efx_StatePD_Type *State_cpcst) {
  sint32 output_value = State_cpcst->Y1 >> 16;
  if (output_value > S8_MAX) {
    output_value = S8_MAX;
  } else if (output_value < S8_MIN) {
    output_value = S8_MIN;
  }
  return (sint8)output_value;
}

// Integral component
void Efx_ICalc(sint32 X_s32, Efx_StateI_Type *State_cpst, sint32 K_s32,
               sint32 dT_s32);
void Efx_ILimCalc(sint32 X_s32, Efx_StateI_Type *State_cpst, sint32 K_s32,
                  const Efx_Limits_Type *Limit_cpst, sint32 dT_s32);
void Efx_CtrlSetLimit(sint32 Min_s32, sint32 Max_s32,
                      Efx_Limits_Type *Limit_cpst);
void Efx_CtrlSetLimits(Efx_Limits_Type *Limit_cpst, sint32 Min_s32,
                       sint32 Max_s32);
__STATIC_FORCEINLINE void Efx_ISetState(Efx_StateI_Type *State_cpst,
                                        sint32 X1_s32, sint16 Y1_s16) {
  State_cpst->Y1 = Y1_s16 << 16;
  State_cpst->X1 = X1_s32;
}
__STATIC_FORCEINLINE sint16 Efx_IOut_s16(const Efx_StateI_Type *State_cpst) {
  sint32 output_value = State_cpst->Y1 >> 16;
  if (output_value > S16_MAX) {
    output_value = S16_MAX;
  } else if (output_value < S16_MIN) {
    output_value = S16_MIN;
  }
  return (sint16)output_value;
}
__STATIC_FORCEINLINE sint8 Efx_IOut_s8(const Efx_StateI_Type *State_cpst) {
  sint32 output_value = State_cpst->Y1 >> 16;
  if (output_value > S8_MAX) {
    output_value = S8_MAX;
  } else if (output_value < S8_MIN) {
    output_value = S8_MIN;
  }
  return (sint8)output_value;
}

// Proportional and Integral controller
void Efx_PITyp1Calc(sint32 X_s32, Efx_StatePI_Type *State_cpst,
                    const Efx_ParamPI_Type *Param_cpst, sint32 dT_s32);
void Efx_PITyp1LimCalc(sint32 X_s32, Efx_StatePI_Type *State_cpst,
                       const Efx_ParamPI_Type *Param_cpst,
                       const Efx_Limits_Type *Limit_cpst, sint32 dT_s32);
void Efx_PITyp2Calc(sint32 X_s32, Efx_StatePI_Type *State_cpst,
                    const Efx_ParamPI_Type *Param_cpst, sint32 dT_s32);
void Efx_PITyp2LimCalc(sint32 X_s32, Efx_StatePI_Type *State_cpst,
                       const Efx_ParamPI_Type *Param_cpst,
                       const Efx_Limits_Type *Limit_cpst, sint32 dT_s32);
__STATIC_FORCEINLINE void Efx_PISetState(Efx_StatePI_Type *State_cpst,
                                         sint32 X1_s32, sint16 Y1_s16) {
  State_cpst->Y1 = Y1_s16 << 16;
  State_cpst->X1 = X1_s32;
}
__STATIC_FORCEINLINE void Efx_PISetParam(Efx_ParamPI_Type *Param_cpst,
                                         sint32 K_s32, sint32 Tnrec) {
  Param_cpst->K_C = K_s32;
  Param_cpst->Tnrec_C = Tnrec;
}
__STATIC_FORCEINLINE sint16 Efx_PIOut_s16(const Efx_StatePI_Type *State_cpst) {
  sint16 output_value = State_cpst->Y1 >> 16;
  if (output_value > S16_MAX) {
    output_value = S16_MAX;
  } else if (output_value < S16_MIN) {
    output_value = S16_MIN;
  }
  return output_value;
}
__STATIC_FORCEINLINE sint8 Efx_PIOut_s8(const Efx_StatePI_Type *State_cpst) {
  sint16 output_value = State_cpst->Y1 >> 16;
  if (output_value > S8_MAX) {
    output_value = S8_MAX;
  } else if (output_value < S8_MIN) {
    output_value = S8_MIN;
  }
  return (sint8)output_value;
}

// Proportional, Integral and Differential controller
void Efx_PIDTyp1Calc(sint32 X_s32, Efx_StatePID_Type *State_cpst,
                     const Efx_ParamPID_Type *Param_cpst, sint32 dT_s32);
void Efx_PIDTyp1LimCalc(sint32 X_s32, Efx_StatePID_Type *State_cpst,
                        const Efx_ParamPID_Type *Param_cpst,
                        const Efx_Limits_Type *Limit_cpst, sint32 dT_s32);
void Efx_PIDTyp2Calc(sint32 X_s32, Efx_StatePID_Type *State_cpst,
                     const Efx_ParamPID_Type *Param_cpst, sint32 dT_s32);
void Efx_PIDTyp2LimCalc(sint32 X_s32, Efx_StatePID_Type *State_cpst,
                        const Efx_ParamPID_Type *Param_cpst,
                        const Efx_Limits_Type *Limit_cpst, sint32 dT_s32);
__STATIC_FORCEINLINE void Efx_PIDSetState(Efx_StatePID_Type *State_cpst,
                                          sint32 X1_s32, sint32 X2_s32,
                                          sint16 Y1_s16) {
  State_cpst->Y1 = Y1_s16 << 16;
  State_cpst->X1 = X1_s32;
  State_cpst->X2 = X2_s32;
}
__STATIC_FORCEINLINE void Efx_PIDSetParam(Efx_ParamPID_Type *Param_cpst,
                                          sint32 K_s32, sint32 Tv_s32,
                                          sint32 Tnrec_s32) {
  Param_cpst->K_C = K_s32;
  Param_cpst->Tv_C = Tv_s32;
  Param_cpst->Tnrec_C = Tnrec_s32;
}
__STATIC_FORCEINLINE sint16
Efx_PIDOut_s16(const Efx_StatePID_Type *State_cpst) {
  sint16 output_value = State_cpst->Y1 >> 16;
  if (output_value > S16_MAX) {
    output_value = S16_MAX;
  } else if (output_value < S16_MIN) {
    output_value = S16_MIN;
  }
  return output_value;
}
__STATIC_FORCEINLINE sint8 Efx_PIDOut_s8(const Efx_StatePID_Type *State_cpst) {
  sint16 output_value = State_cpst->Y1 >> 16;
  if (output_value > S8_MAX) {
    output_value = S8_MAX;
  } else if (output_value < S8_MIN) {
    output_value = S8_MIN;
  }
  return (sint8)output_value;
}

// Square root
uint32 Efx_Sqrt_u32_u32(uint32 x_value);
uint16 Efx_Sqrt_u16_u16(uint16 x_value);
uint8 Efx_Sqrt_u8_u8(uint8 x_value);

// Average
sint32 Efx_Average_s32_s32(sint32 value1, sint32 value2);

// Array Average
sint32 Efx_Array_Average_s32_s32(const sint32 *Array, uint16 Count);
sint16 Efx_Array_Average_s16_s16(const sint16 *Array, uint16 Count);

// Moving Average
sint16 Efx_MovingAverage_s16_s16(Efx_MovingAvrgS16_Type *state, sint16 value);
sint32 Efx_MovingAverage_s32_s32(Efx_MovingAvrgS32_Type *state, sint32 value);

// Hypotenuse
uint32 Efx_Hypot_u32u32_u32(uint32 x_value, uint32 y_value);
uint16 Efx_Hypot_u16u16_u16(uint16 x_value, uint16 y_value);
uint8 Efx_Hypot_u8u8_u8(uint8 x_value, uint8 y_value);

// Trigonometric functions
sint32 Efx_Sin_s32_s32(sint32 x_value);
sint16 Efx_Sin_s16_s16(sint16 x_value);
sint8 Efx_Sin_s8_s8(sint8 x_value);
sint32 Efx_Cos_s32_s32(sint32 x_value);
sint16 Efx_Cos_s16_s16(sint16 x_value);
sint8 Efx_Cos_s8_s8(sint8 x_value);
sint32 Efx_Arcsin_s32_s32(sint32 x_value);
sint16 Efx_Arcsin_s16_s16(sint16 x_value);
sint8 Efx_Arcsin_s8_s8(sint8 x_value);
uint32 Efx_Arccos_s32_u32(sint32 x_value);
uint16 Efx_Arccos_s16_u16(sint16 x_value);
uint8 Efx_Arccos_s8_u8(sint8 x_value);

// Rate limiter
void Efx_SlewRate_u16(uint16 limit_pos, uint16 input, uint16 limit_neg,
                      uint16 *output, uint8 *init);
void Efx_SlewRate_s16(sint16 limit_pos, sint16 input, sint16 limit_neg,
                      sint16 *output, uint8 *init);
void Efx_SlewRate_u32(uint32 limit_pos, uint32 input, uint32 limit_neg,
                      uint32 *output, uint8 *init);
void Efx_SlewRate_s32(sint32 limit_pos, sint32 input, sint32 limit_neg,
                      sint32 *output, uint8 *init);

// Ramp routine
void Efx_RampCalc(sint32 X_s32, Efx_StateRamp_Type *State_cpst,
                  const Efx_ParamRamp_Type *Param_cpcst, sint32 dT_s32);
void Efx_RampInitState(Efx_StateRamp_Type *State_cpst, sint32 Val_s32);
void Efx_RampSetParam(Efx_ParamRamp_Type *Param_cpst, uint32 SlopePosVal_u32,
                      uint32 SlopeNegVal_u32);
sint32 Efx_RampOut_s32(const Efx_StateRamp_Type *State_cpcst);
void Efx_RampCalcJump(sint32 X_s32, Efx_StateRamp_Type *State_cpst);
sint32 Efx_RampCalcSwitch_s32(sint32 Xa_s32, sint32 Xb_s32,
                              Efx_StateRamp_Type *State_cpst,
                              const Efx_ParamRamp_Type *Param_cpcst,
                              sint32 dT_s32);
sint32 Efx_RampCalcSwitch(sint32 Xa_s32, sint32 Xb_s32, boolean Switch,
                          Efx_StateRamp_Type *State_cpst);
boolean Efx_RampGetSwitchPos(const Efx_StateRamp_Type *State_cpst);
boolean Efx_RampCheckActivity(const Efx_StateRamp_Type *State_cpst);

// Hysteresis routines
uint8 Efx_Hysteresis_u8_u8(uint8 input, uint8 thresholdLow, uint8 thresholdHigh,
                           uint8 Out_Val, uint8 Out_LowThresholdVal,
                           uint8 Out_HighThresholdVal);
uint16 Efx_Hysteresis_u16_u16(uint16 input, uint16 thresholdLow,
                              uint16 thresholdHigh, uint16 Out_Val,
                              uint16 Out_LowThresholdVal,
                              uint16 Out_HighThresholdVal);
uint32 Efx_Hysteresis_u32_u32(uint32 input, uint32 thresholdLow,
                              uint32 thresholdHigh, uint32 Out_Val,
                              uint32 Out_LowThresholdVal,
                              uint32 Out_HighThresholdVal);
sint8 Efx_Hysteresis_s8_s8(sint8 input, sint8 thresholdLow, sint8 thresholdHigh,
                           sint8 Out_Val, sint8 Out_LowThresholdVal,
                           sint8 Out_HighThresholdVal);
sint16 Efx_Hysteresis_s16_s16(sint16 input, sint16 thresholdLow,
                              sint16 thresholdHigh, sint16 Out_Val,
                              sint16 Out_LowThresholdVal,
                              sint16 Out_HighThresholdVal);
sint32 Efx_Hysteresis_s32_s32(sint32 input, sint32 thresholdLow,
                              sint32 thresholdHigh, sint32 Out_Val,
                              sint32 Out_LowThresholdVal,
                              sint32 Out_HighThresholdVal);

boolean Efx_HystCenterHalfDelta_s32_u8(sint32 X, sint32 center,
                                       sint32 halfDelta, boolean *State);
boolean Efx_HystCenterHalfDelta_u32_u8(uint32 X, uint32 center,
                                       uint32 halfDelta, boolean *State);
boolean Efx_HystCenterHalfDelta_s8_u8(sint8 X, sint8 center, sint8 halfDelta,
                                      boolean *State);
boolean Efx_HystCenterHalfDelta_u8_u8(uint8 X, uint8 center, uint8 halfDelta,
                                      boolean *State);
boolean Efx_HystCenterHalfDelta_s16_u8(sint16 X, sint16 center,
                                       sint16 halfDelta, boolean *State);
boolean Efx_HystCenterHalfDelta_u16_u8(uint16 X, uint16 center,
                                       uint16 halfDelta, boolean *State);

boolean Efx_HystLeftRight_s32_u8(sint32 X, sint32 Lsp, sint32 Rsp,
                                 boolean *State);
boolean Efx_HystLeftRight_u32_u8(uint32 X, uint32 Lsp, uint32 Rsp,
                                 boolean *State);
boolean Efx_HystLeftRight_s8_u8(sint8 X, sint8 Lsp, sint8 Rsp, boolean *State);
boolean Efx_HystLeftRight_u8_u8(uint8 X, uint8 Lsp, uint8 Rsp, boolean *State);
boolean Efx_HystLeftRight_s16_u8(sint16 X, sint16 Lsp, sint16 Rsp,
                                 boolean *State);
boolean Efx_HystLeftRight_u16_u8(uint16 X, uint16 Lsp, uint16 Rsp,
                                 boolean *State);

boolean Efx_HystDeltaRight_s32_u8(sint32 X, sint32 Delta, sint32 Rsp,
                                  boolean *State);
boolean Efx_HystDeltaRight_u32_u8(uint32 X, uint32 Delta, uint32 Rsp,
                                  boolean *State);
boolean Efx_HystDeltaRight_s8_u8(sint8 X, sint8 Delta, sint8 Rsp,
                                 boolean *State);
boolean Efx_HystDeltaRight_u8_u8(uint8 X, uint8 Delta, uint8 Rsp,
                                 boolean *State);
boolean Efx_HystDeltaRight_s16_u8(sint16 X, sint16 Delta, sint16 Rsp,
                                  boolean *State);
boolean Efx_HystDeltaRight_u16_u8(uint16 X, uint16 Delta, uint16 Rsp,
                                  boolean *State);

boolean Efx_HystLeftDelta_s32_u8(sint32 X, sint32 Lsp, sint32 Delta,
                                 boolean *State);
boolean Efx_HystLeftDelta_u32_u8(uint32 X, uint32 Lsp, uint32 Delta,
                                 boolean *State);
boolean Efx_HystLeftDelta_s8_u8(sint8 X, sint8 Lsp, sint8 Delta,
                                boolean *State);
boolean Efx_HystLeftDelta_u8_u8(uint8 X, uint8 Lsp, uint8 Delta,
                                boolean *State);
boolean Efx_HystLeftDelta_s16_u8(sint16 X, sint16 Lsp, sint16 Delta,
                                 boolean *State);
boolean Efx_HystLeftDelta_u16_u8(uint16 X, uint16 Lsp, uint16 Delta,
                                 boolean *State);

// Efx_DeadTime
sint16 Efx_DeadTime_s16_s16(sint16 X, sint32 DelayTime, sint32 StepTime,
                            Efx_DeadTimeParam_Type *Param);
// Debounce routines
boolean Efx_Debounce_u8_u8(boolean X, Efx_DebounceState_Type *State,
                           const Efx_DebounceParam_Type *Param, sint32 dT);
void Efx_DebounceInit(Efx_DebounceState_Type *State, boolean X);
void Efx_DebounceSetParam(Efx_DebounceParam_Type *Param, sint16 THighLow,
                          sint16 TLowHigh);

// Ascending Sort Routine
void Efx_SortAscend_s8(sint8 *Array, uint16 Num);
void Efx_SortAscend_u8(uint8 *Array, uint16 Num);
void Efx_SortAscend_u16(uint16 *Array, uint16 Num);
void Efx_SortAscend_s16(sint16 *Array, uint16 Num);
void Efx_SortAscend_u32(uint32 *Array, uint16 Num);
void Efx_SortAscend_s32(sint32 *Array, uint16 Num);

// Descending Sort Routine
void Efx_SortDescend_s8(sint8 *Array, uint16 Num);
void Efx_SortDescend_u8(uint8 *Array, uint16 Num);
void Efx_SortDescend_u16(uint16 *Array, uint16 Num);
void Efx_SortDescend_s16(sint16 *Array, uint16 Num);
void Efx_SortDescend_u32(uint32 *Array, uint16 Num);
void Efx_SortDescend_s32(sint32 *Array, uint16 Num);

// Median sort routine
uint8 Efx_MedianSort_u8_u8(uint8 *Array, uint8 N);
uint16 Efx_MedianSort_u16_u16(uint16 *Array, uint8 N);
sint16 Efx_MedianSort_s16_s16(sint16 *Array, uint8 N);
sint8 Efx_MedianSort_s8_s8(sint8 *Array, uint8 N);
uint32 Efx_MedianSort_u32_u32(uint32 *Array, uint8 N);
sint32 Efx_MedianSort_s32_s32(sint32 *Array, uint8 N);

// Edge detection routines
boolean Efx_EdgeBipol_u8_u8(boolean Inp_Val, boolean *Old_Val);
boolean Efx_EdgeFalling_u8_u8(boolean Inp_Val, boolean *Old_Val);
boolean Efx_EdgeRising_u8_u8(boolean Inp_Val, boolean *Old_Val);

// Interval routines
boolean Efx_IntervalClosed_s32_u8(sint32 MinVal, sint32 InpVal, sint32 MaxVal);
boolean Efx_IntervalClosed_u32_u8(uint32 MinVal, uint32 InpVal, uint32 MaxVal);
boolean Efx_IntervalOpen_s32_u8(sint32 MinVal, sint32 InpVal, sint32 MaxVal);
boolean Efx_IntervalOpen_u32_u8(uint32 MinVal, uint32 InpVal, uint32 MaxVal);
boolean Efx_IntervalLeftOpen_s32_u8(sint32 MinVal, sint32 InpVal,
                                    sint32 MaxVal);
boolean Efx_IntervalLeftOpen_u32_u8(uint32 MinVal, uint32 InpVal,
                                    uint32 MaxVal);
boolean Efx_IntervalRightOpen_s32_u8(sint32 MinVal, sint32 InpVal,
                                     sint32 MaxVal);
boolean Efx_IntervalRightOpen_u32_u8(uint32 MinVal, uint32 InpVal,
                                     uint32 MaxVal);

// Counter routines
void Efx_CounterSet_u16(uint16 *CounterVal, uint16 Val);
void Efx_CounterSet_u32(uint32 *CounterVal, uint32 Val);
void Efx_CounterSet_u8(uint8 *CounterVal, uint8 Val);
uint8 Efx_Counter_u8_u8(uint8 *CounterVal);
uint16 Efx_Counter_u16_u16(uint16 *CounterVal);
uint32 Efx_Counter_u32_u32(uint32 *CounterVal);

// Flip-Flop routine
boolean Efx_RSFlipFlop(boolean R_Val, boolean S_Val, boolean *State_Val);

// Limiter routines
uint8 Efx_TypeLimiter_s32_u8(sint32 Input_Val);
uint16 Efx_TypeLimiter_s32_u16(sint32 Input_Val);
uint32 Efx_TypeLimiter_s32_u32(sint32 Input_Val);
sint8 Efx_TypeLimiter_s32_s8(sint32 Input_Val);
sint16 Efx_TypeLimiter_s32_s16(sint32 Input_Val);
uint8 Efx_TypeLimiter_u32_u8(uint32 Input_Val);
uint16 Efx_TypeLimiter_u32_u16(uint32 Input_Val);
sint32 Efx_TypeLimiter_u32_s32(uint32 Input_Val);
sint8 Efx_TypeLimiter_u32_s8(uint32 Input_Val);
sint16 Efx_TypeLimiter_u32_s16(uint32 Input_Val);
uint8 Efx_TypeLimiter_s16_u8(sint16 Input_Val);
uint16 Efx_TypeLimiter_s16_u16(sint16 Input_Val);
sint8 Efx_TypeLimiter_s16_s8(sint16 Input_Val);
uint8 Efx_TypeLimiter_u16_u8(uint16 Input_Val);
sint8 Efx_TypeLimiter_u16_s8(uint16 Input_Val);
sint16 Efx_TypeLimiter_u16_s16(uint16 Input_Val);
uint8 Efx_TypeLimiter_s8_u8(sint8 Input_Val);
sint8 Efx_TypeLimiter_u8_s8(uint8 Input_Val);

// 64 bits functions
sint64 Efx_Cast_u32_s64(uint32 x_value);
uint32 Efx_Cast_s64_u32(sint64 x_value);
sint32 Efx_Cast_s64_s32(sint64 x_value);

sint64 Efx_Add_s64s32_s64(sint64 x_value, sint32 y_value);
sint64 Efx_Add_s64u32_s64(sint64 x_value, uint32 y_value);
sint64 Efx_Add_s64s64_s64(sint64 x_value, sint64 y_value);
sint64 Efx_Mul_s64u32_s64(sint64 x_value, uint32 y_value);
sint64 Efx_Mul_s64s32_s64(sint64 x_value, sint32 y_value);
sint64 Efx_Mul_s64s64_s64(sint64 x_value, sint64 y_value);
sint64 Efx_Div_s64u32_s64(sint64 x_value, uint32 y_value);
sint64 Efx_Div_s64s32_s64(sint64 x_value, sint32 y_value);
sint32 Efx_Div_s64s32_s32(sint64 x_value, sint32 y_value);
uint32 Efx_Div_s64s32_u32(sint64 x_value, sint32 y_value);
sint32 Efx_Div_s64u32_s32(sint64 x_value, uint32 y_value);
uint32 Efx_Div_s64u32_u32(sint64 x_value, uint32 y_value);

boolean Efx_Gt_s64u32_u8(sint64 x_value, uint32 y_value);
boolean Efx_Gt_s64s32_u8(sint64 x_value, sint32 y_value);

#endif
